/**
	Audier1 - Commandline app to batch edit id3 tags in audio files
	
	Email	:	hypercas@gmail.com
	Created :	16/Feb/2011
	Modified:	19/Mar/2011
**/
#include "audier.h"

namespace Audier
{

bool Album::DirectoryGetFiles(fs::path dirpath)
{
	//Verify directory is vaild
	if ( fs::is_directory( dirpath ) )
	{
		fs::directory_iterator end_iter;

		//Loop through directory
	    for ( fs::directory_iterator dir_itr( dirpath ); dir_itr != end_iter; ++dir_itr )
		{
			//Check file type
			if ( fs::is_regular_file( dir_itr->status() ) && dir_itr->path().extension() == ab_meta["file_ext"] )
			{
				//Add required files to file list
				dir_files.push_back( dir_itr->path().filename() );
			}
		}

		//Output: number of files to process
		std::cout<<"\n[*"<<ab_meta["file_ext"]<<"] "<<dir_files.size()<<" file(s) to process";
		return true;
	}
	else
	{
		//Display error on invalid directory path
		std::cout << "\nDirectory Not found: " << dirpath.file_string() << std::endl;
		return false;
	}
}

bool Album::DirectoryGetPicture( fs::path dirpath )
{
	//Check for valid directory path
	if ( fs::is_directory( dirpath ) )
	{
		//Loop through directory for an image file
		fs::directory_iterator end_iter;
	    for (	fs::directory_iterator dir_itr( dirpath );
				dir_itr != end_iter;
				++dir_itr )
		{
			if ( fs::is_regular_file( dir_itr->status() ) )
			{
				if( dir_itr->path().extension() == ".jpg" 
					|| dir_itr->path().extension() == ".png" )
				{
					ab_meta["picture"] = dir_itr->path().string();
					return true;
				}
			}
		}

	}

	return false;
}

bool Album::FileUpdate(unsigned int file_id)
{
	//Check if file_id is valid
	if(file_id >= dir_files.size())return false;
	
	//Output filename
	std::cout<<"\n\n[FILE] "<<dir_files[file_id].c_str();

	//TagLib File ref
	TagLib::FileRef tag_file(dir_files[file_id].c_str());

	//Check if file could be opened
	if(tag_file.isNull())return false;

	//Tag pointer
	TagLib::Tag *tag = tag_file.tag();

	//Check if there is a valid tag
	if(!tag)return false;

	//Track number from file_id
	unsigned int track = boost::lexical_cast<unsigned int>(ab_meta["track_start"]) + file_id + 1;

	//Track Number
	{
		std::cout<<"\n\t[Track] "<<tag->track()<<" -> "<<track;
		tag->setTrack(track);
	}

	//Track Title
	{			
		if(ab_meta["title"].size()>0)
		{
			std::ostringstream title;
			title<<std::setw(3)<<std::setfill('0')<<track<<" "<<ab_meta["title"];
			std::cout<<"\n\t[Title] "<<tag->title()<<" -> "<<title.str();
			tag->setTitle(title.str());
		}
	}

	//Album
	{
		if(ab_meta["album"].size()>0)
		{
			std::cout<<"\n\t[Album] "<<tag->album()<<" -> "<<ab_meta["album"];
			tag->setAlbum(ab_meta["album"]);
		}
	}

	//Artist
	{
		if(ab_meta["artist"].size()>0)
		{
			std::cout<<"\n\t[Artist] "<<tag->artist()<<" -> "<<ab_meta["artist"];
			tag->setArtist(ab_meta["artist"]);
		}
	}

	//Genre
	{
		if(ab_meta["genre"].size()>0)
		{
			std::cout<<"\n\t[Genre] "<<tag->genre()<<" -> "<<ab_meta["genre"];
			tag->setGenre(ab_meta["genre"]);
		}
	}

	//Year
	{
		if(ab_meta["year"].size()>0)
		{
			std::cout<<"\n\t[Year] "<<tag->year()<<" -> "<<ab_meta["year"];
			tag->setYear(boost::lexical_cast<unsigned int>(ab_meta["year"]));
		}
	}
	
	//Save changes
	if(!tag_file.save())std::cout<<"\n--Save failed";

	//Picture
	{
		if(ab_meta["picture"].size()>0)
		{
			//tag->set unavilable
			TagLib::MPEG::File audioFile( dir_files[file_id].c_str() );
			ImageFile imageFile( ab_meta["picture"].c_str() );

			if(!audioFile.isValid()) {
				std::cout << '\n\t"' << audioFile.name() << "\" is not valid." << std::endl;
				return false;
			}
			if(!imageFile.isValid()) {
				std::cout << '\n\t"' << imageFile.name() << "\" is not valid." << std::endl;
				return false;
			}

			TagLib::ID3v2::Tag *tag = audioFile.ID3v2Tag(true);
			TagLib::ID3v2::AttachedPictureFrame *frame = NULL;

			TagLib::ID3v2::FrameList l = tag->frameList("APIC");
			
			if(l.isEmpty())
			{
				//Add a picture
				frame = new TagLib::ID3v2::AttachedPictureFrame;

				frame->setMimeType(imageFile.mimeType());
				frame->setPicture(imageFile.data());

				tag->addFrame(frame);
				std::cout<<"\n\t[Picture] New -> "<<ab_meta["picture"];
			}
			else
			{
				frame = static_cast<TagLib::ID3v2::AttachedPictureFrame *>(l.front());
				frame->setMimeType(imageFile.mimeType());
				frame->setPicture(imageFile.data());

				std::cout<<"\n\t[Picture] Replace -> "<<ab_meta["picture"];
			}

			audioFile.save();
			

		}
	}

	return true;
}

bool Album::FileAutoProcess()
{
	for(unsigned int i=0;i<dir_files.size();i++)
	{
		FileUpdate(i);
	}
	return true;
}

void Album::CreateMetaMap()
{
	ab_meta["album"]	= "";
	ab_meta["title"]	= "";
	ab_meta["year"]		= "";
	ab_meta["artist"]	= "";
	ab_meta["genre"]	= "";
	ab_meta["picture"]	= "";				// picture (file path)
	ab_meta["file_ext"]	= ".mp3";			// file extension
	ab_meta["track_start"]	= "0";			// initial track number
}

Album::Album()
{
	CreateMetaMap();
}

}
